﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Windows.Forms;

/// <summary>
///图片采集类
/// </summary>
public class GetBingMapImages : Form
{

    private int ZoomLevel = 15;

    public void GetIMages()
    {
        ///初始化生成集合
        LevelStrings = new List<List<string>>();
        ///r132121
        /////
        //默認是1級 區域太大了
        //var baseLevel = new List<string> { "1321210", "1321211", "1321212", "1321213" };//, "1", "2", "3" 
        //這個是蘇州的區域 "1321210113", "1321210131", "1321210133"
        //這個是上海區域 
        //132121103
        //132121102
        //132121100
        //132121101
        //132121120
        //CreateQuadKeyAddToCollection(baseLevel, ZoomLevel);

        //得到總數
        GetCycleCount(baseLevel, ZoomLevel);

        DownLoadFile();
    }

    private WebBrowser wb = null;

    #region 采集
    /// <summary>
    /// 开始下载文件
    /// </summary>

    private PictureBox pic;
    /// <summary>
    /// 當前採集的圖
    /// </summary>
    public PictureBox Pic
    {
        get { return pic; }
        set { pic = value; }
    }

    public BingMap数据采集.Form1 Parent
    {
        get;
        set;
    }

    /// <summary>
    ///初始化地圖區域 
    /// </summary>
    //默認是1級 區域太大了
    //var baseLevel = new List<string> { "1321210", "1321211", "1321212", "1321213" };//, "1", "2", "3" 
    //這個是蘇州的區域 "1321210113", "1321210131", "1321210133"
    //這個是上海區域 
    //132121103
    //132121102
    //132121100
    //132121101
    //132121120
    private List<string> baseLevel = new List<string> { "132121103", "132121102", "132121100", "132121101", "132121120" };
    /// <summary>
    ///初始化地圖區域
    /// </summary>
    public List<string> BaseLevel
    {
        get { return baseLevel; }
        set { baseLevel = value; }
    }


    public int ThrCount = 0;

    void DownLoadFile()
    {

        //集合总数
        SingleCollectionState.Instance.Count = Count;
        if (ThrCount < 10)
        {

            System.Threading.Thread thr1 = new System.Threading.Thread(new System.Threading.ThreadStart(
            delegate
            {
                if (SingleCollectionState.Instance.CurrentIndex == 1)
                {
                    load(false, 0, int.Parse(SingleCollectionState.Instance.Count.ToString("f0")), baseLevel, ZoomLevel);

                }
                else
                {
                    ///跳過的數
                    int skip = int.Parse(Math.Round((SingleCollectionState.Instance.Count - SingleCollectionState.Instance.CurrentIndex) / 10).ToString("f0"));
                    int take = int.Parse(Math.Round((SingleCollectionState.Instance.Count - SingleCollectionState.Instance.CurrentIndex) / 10).ToString("f0"));
                    //採集資料
                    load(false, skip * ThrCount, take, baseLevel, ZoomLevel);
                }
            }
                ));
            thr1.Start();
            ThrCount++;
        }


    }
    /// <summary>
    /// 當前工作路徑
    /// AppDomain.CurrentDomain.BaseDirectory + "ShangHaiMap"
    /// </summary>
    public string BaseUrl = @"E:\網站項目\SilverLight\Silverlight探秘系列课程\使用多媒体.Web\ShangHaiMap";

    /// <summary>
    /// 是不是替換
    /// </summary>
    ///<param name="IsOverWritten">是不是重新替換圖片</param>
    ///<param name="skipCurrent">跳過的圖片數</param>
    ///<param name="takeCurrent">當前要採集的圖片數年</param>
    ///<param name="baseLevel">基本图像区域</param>
    ///<param name="endLevel">指定最大放大等级 最大23</param>
    void load(bool IsOverWritten, int skipCurrent, int takeCurrent, List<string> baseLevel, int endLevel)
    {
        var i = 0;
        var downnum = 0;
        System.Net.WebClient wc = new System.Net.WebClient();
        //如果不存在這個目錄
        if (!System.IO.Directory.Exists(BaseUrl))
        {
            System.IO.Directory.CreateDirectory(BaseUrl);
        }



        #region 自己一個一個的算


        #region 加入自己生與所有以上級別的單個圖
        var BaseString = new List<string>();
        for (int n = 0; n < baseLevel[0].Length; n++)
        {
            //遍歷所有字段
            foreach (var str in baseLevel)
            {
                //保存不出錯
                if (str.Length > n)
                {
                    string tempStr = str.Substring(0, str.Length - n);
                    if (!BaseString.Contains(tempStr))
                    {
                        //添加到集合不採集重復項
                        BaseString.Add(tempStr);
                        #region 查看條件進行採集
                        if (i < skipCurrent)
                        {
                            i++;

                        }
                        else
                        {
                            //下載記數
                            if (downnum <= takeCurrent)
                            {

                                ///寫文件
                                WriteFile(IsOverWritten, tempStr, wc);
                                //線程下載記數
                                downnum++;

                            }
                        }
                        #endregion
                    }
                }
            }
        }
        #endregion
        #region 構成這個等級的所有 string
         //开始采集数据
        foreach (var strN in baseLevel)
        {

            CycleGetPic(strN, baseLevel[0].Length, ZoomLevel, IsOverWritten, skipCurrent, takeCurrent, downnum, i, new System.Net.WebClient());
        }
        #endregion



        //清空變量
        BaseString.Clear();
        BaseString = null;
        #endregion
    }

    /// <summary>
    /// 递归计算 采集 数据
    /// </summary>
    /// <param name="baseTilNum">基图像编码数据</param>
    /// <param name="CurrentLevel">当前放大倍数</param>
    /// <param name="MaxLevel">最大放大倍数</param>
    /// <param name="CurrentCycleNum">当前循环的数</param>
    /// <param name="downnum">当前函数下载的记数</param>
    ///<param name="skipCurrent">跳過的圖片數</param>
    ///<param name="takeCurrent">當前要採集的圖片數年</param>
    ///<param name="IsOverWritten">是不是重新替換圖片</param>
    ///<param name="wc">下载图片的对像</param>
    void CycleGetPic(string baseTilNum, int CurrentLevel, int MaxLevel, bool IsOverWritten, int skipCurrent, int takeCurrent, int downnum, int CurrentCycleNum, System.Net.WebClient wc)
    {
        if (CurrentLevel <= MaxLevel)
        {
            #region 开始采集
            foreach (var strN in "0123".ToCharArray())
            {
                #region 查看條件進行採集
                //没到到达任务开始的位置
                if (CurrentCycleNum < skipCurrent)
                {
                    //记数加1
                    CurrentCycleNum = CurrentCycleNum+1;
                }
                else
                {
                    //下載記數
                    if (downnum <= takeCurrent)
                    {

                        try
                        {
                            ///寫文件
                            WriteFile(IsOverWritten, baseTilNum + strN, wc);
                        }
                        catch (System.Net.WebException webEx)
                        {
                            Parent.BeginInvoke(new Action(delegate
                            {
                                Parent.ttExceptionTextBox.Text += webEx.Message + "'" + baseTilNum + strN + "'" + "\r\n";
                            }));
                        }
                        catch (System.NotSupportedException 没有实现的异常)
                        {
                            Parent.BeginInvoke(new Action(delegate
                            {
                                Parent.ttExceptionTextBox.Text += 没有实现的异常.Message + "'" + baseTilNum + strN + "'" + "\r\n";
                            }));
                        }
                        catch (System.ObjectDisposedException)
                        { 
                            
                        }
                        catch (System.InvalidOperationException)
                        {

                        }

                        //線程下載記數
                        downnum = downnum + 1;

                        //已经完成数
                        SingleCollectionState.Instance.CurrentIndex++;

                        //采集下一个级别的图片
                        CycleGetPic(baseTilNum + strN, (CurrentLevel + 1), MaxLevel, IsOverWritten, skipCurrent, takeCurrent, downnum, CurrentCycleNum,wc);

                    }
                    else
                    {
                        //表示当前线程已经完成了分配给他的任务
                        return;
                    }
                }
                #endregion
            }

            #endregion

            CurrentLevel = CurrentLevel + 1;

            
        }
        else
        {
            return;
        }
    }

    /// <summary>
    /// 寫入文件
    /// </summary>
    /// <param name="IsOverWritten"></param>
    /// <param name="str"></param>
    void WriteFile(bool IsOverWritten, string str, System.Net.WebClient wc)
    {

        //如果替換
        if (IsOverWritten)
        {

            byte[] bytearray = wc.DownloadData(SingleCollectionState.Instance.CurrentGetUrl + str + ".png?g=49");

            //顯示圖片
            Parent.Invoke(new Action(delegate { Pic.Image = System.Drawing.Image.FromStream(new System.IO.MemoryStream(bytearray)); }));

            System.IO.File.WriteAllBytes(BaseUrl + "/" + SingleCollectionState.Instance.CurrentGetUrl.ToCharArray().Last() + str + ".png", bytearray);
            //已经完成数
            SingleCollectionState.Instance.CurrentIndex++;
            bytearray = null;
        }
        else
        {
            ///如果存在
            if (System.IO.File.Exists(BaseUrl + "/" + SingleCollectionState.Instance.CurrentGetUrl.ToCharArray().Last() + str + ".png"))
            {
                //已经完成数
                SingleCollectionState.Instance.CurrentIndex++;
            }
            else
            {
                byte[] bytearray = wc.DownloadData(SingleCollectionState.Instance.CurrentGetUrl + str + ".png?g=49");

                //顯示圖片
                Parent.Invoke(new Action(delegate { Pic.Image = System.Drawing.Image.FromStream(new System.IO.MemoryStream(bytearray)); }));
                try
                {
                    System.IO.File.WriteAllBytes(BaseUrl + "/" + SingleCollectionState.Instance.CurrentGetUrl.ToCharArray().Last() + str + ".png", bytearray);
                    //已经完成数
                    SingleCollectionState.Instance.CurrentIndex++;

                }
                catch (System.IO.IOException ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex.ToString());
                }
                bytearray = null;
            }
        }
    }


    #endregion

    int Count = 0;

    /// <summary>
    /// 变量
    /// </summary>
    List<List<string>> LevelStrings = new List<List<string>>();


    /// <summary>
    /// 得到計算總數
    /// </summary>
    ///<param name="baseLevel">基本图像区域</param>
    ///<param name="endLevel">指定最大放大等级 最大23</param>
    void GetCycleCount(List<string> baseLevel, int endLevel)
    {
        Count = 0;
        var baseLevelCopy = baseLevel.ToList();

        #region 加入自己生與所有以上級別的單個圖
        var BaseString = new List<string>();
        for (int n = 0; n < baseLevelCopy[0].Length; n++)
        {
            //遍歷所有字段
            foreach (var str in baseLevelCopy)
            {
                //保存不出錯
                if (str.Length > n)
                {
                    string tempStr = str.Substring(0, str.Length - n);
                    if (!BaseString.Contains(tempStr))
                    {
                        BaseString.Add(tempStr);
                        Count++;
                    }
                }
            }
        }
        #endregion
        //缩放等级

        // 递归计算总数
        GetCycleCount(baseLevelCopy.Count, baseLevelCopy[0].Length, endLevel);


    }

    /// <summary>
    /// 递归计算数据
    /// </summary>
    /// <param name="baseTileNum">基图像数据</param>
    /// <param name="CurrentLevel">当前放大倍数</param>
    /// <param name="MaxLevel">最大放大倍数</param>
    void GetCycleCount(int baseTileNum, int CurrentLevel, int MaxLevel)
    {

        if (CurrentLevel <= MaxLevel)
        {
            //总数
            Count += baseTileNum * 4;
            CurrentLevel = CurrentLevel + 1;
            GetCycleCount(baseTileNum * 4, CurrentLevel, MaxLevel);
        }
        else
        {
            return;
        }

    }

    /// <summary>
    /// 生成指定 区域图下的指定缩放等级的图的列表集合
    /// </summary>
    ///<param name="baseLevel">基本图像区域</param>
    ///<param name="endLevel">指定最大放大等级 最大23</param>
    void CreateQuadKeyAddToCollection(List<string> baseLevel, int endLevel)
    {
        Count = 0;

        #region 加入自己生與所有以上級別的單個圖
        var BaseString = new List<string>();
        for (int n = 0; n < baseLevel[0].Length; n++)
        {
            //遍歷所有字段
            foreach (var str in baseLevel)
            {
                //保存不出錯
                if (str.Length > n)
                {
                    string tempStr = str.Substring(0, str.Length - n);
                    if (!BaseString.Contains(tempStr))
                    {
                        BaseString.Add(tempStr);
                        Count++;
                    }
                }
            }
        }
        #endregion

        //將當前級別及當前級別的資料添加到集合
        LevelStrings.Add(BaseString);

        for (int Level = baseLevel[0].Length; Level <= endLevel; Level++)
        {
            var tempString = new List<string>();

            #region 構成這個等級的所有 string
            foreach (var str in baseLevel)
            {
                foreach (var strN in "0123".ToCharArray())
                {
                    tempString.Add(str + strN);
                    Count++;
                }
            }



            #endregion

            LevelStrings.Add(tempString);

            baseLevel = tempString;

        }

    }
}
